﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows;

namespace Dotway.WPF.Panels
{
    public class ZipperPanel : Panel
    {
        #region Constructors

        public ZipperPanel()
            : base()
        { }

        #endregion Constructors
        #region Properties

        public static readonly DependencyProperty ChildrenPerRowProperty = DependencyProperty.Register("ChildrenPerRow", typeof(int), typeof(ZipperPanel), new FrameworkPropertyMetadata(2, FrameworkPropertyMetadataOptions.AffectsMeasure));
        public int ChildrenPerRow
        {
            get { return (int)GetValue(ChildrenPerRowProperty); }
            set { SetValue(ChildrenPerRowProperty, value); }
        }

        public static readonly DependencyProperty ColumnOffsetProperty = DependencyProperty.Register("ColumnOffset", typeof(double), typeof(ZipperPanel), new FrameworkPropertyMetadata(12.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
        public double ColumnOffset
        {
            get { return (double)GetValue(ColumnOffsetProperty); }
            set { SetValue(ColumnOffsetProperty, value); }
        }

        public static readonly DependencyProperty RowOffsetProperty = DependencyProperty.Register("RowOffset", typeof(double), typeof(ZipperPanel), new FrameworkPropertyMetadata(3.5, FrameworkPropertyMetadataOptions.AffectsMeasure));
        public double RowOffset
        {
            get { return (double)GetValue(RowOffsetProperty); }
            set { SetValue(RowOffsetProperty, value); }
        }

        public static readonly DependencyProperty SpacingYProperty = DependencyProperty.Register("SpacingY", typeof(double), typeof(ZipperPanel), new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
        public double SpacingY
        {
            get { return (double)GetValue(SpacingYProperty); }
            set { SetValue(SpacingYProperty, value); }
        }

        public static readonly DependencyProperty SpacingXProperty = DependencyProperty.Register("SpacingX", typeof(double), typeof(ZipperPanel), new FrameworkPropertyMetadata(12.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
        public double SpacingX
        {
            get { return (double)GetValue(SpacingXProperty); }
            set { SetValue(SpacingXProperty, value); }
        }

        public static readonly DependencyProperty LeftProperty = DependencyProperty.Register("Left", typeof(double), typeof(ZipperPanel), new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
        public double Left
        {
            get { return (double)GetValue(LeftProperty); }
            set { SetValue(LeftProperty, value); }
        }

        public static readonly DependencyProperty TopProperty = DependencyProperty.Register("Top", typeof(double), typeof(ZipperPanel), new FrameworkPropertyMetadata(10.0, FrameworkPropertyMetadataOptions.AffectsMeasure));
        public double Top
        {
            get { return (double)GetValue(TopProperty); }
            set { SetValue(TopProperty, value); }
        }

        #endregion Properties
        #region Methods

        protected override Size MeasureOverride(Size availableSize)
        {
            Size childSize = availableSize;

            double maxWidth = 0.0;
            double maxHeight = 0.0;
            double x = Left;
            double y = Top;

            for (int i = 0; i < InternalChildren.Count; i++)
            {
                UIElement child = InternalChildren[i];
                child.Measure(childSize);

                double width = child.DesiredSize.Width + x;
                double height = child.DesiredSize.Height + y;
                if (width > maxWidth)
                {
                    maxWidth = width;
                }

                if (height > maxHeight)
                {
                    maxHeight = height;
                }

                y += SpacingY;
                if ((i + 1) % ChildrenPerRow == 0)
                {
                    x -= SpacingX * (ChildrenPerRow - 1);
                    x += RowOffset;
                    y += ColumnOffset;
                }
                else
                {
                    x += SpacingX;
                }
            }

            return new Size(maxWidth, maxHeight);
        }
        protected override Size ArrangeOverride(Size finalSize)
        {
            double x = Left;
            double y = Top;

            for (int i = 0; i < InternalChildren.Count; i++)
            {
                UIElement child = InternalChildren[i];
                child.Arrange(new Rect(new Point(x, y), child.DesiredSize));

                y += SpacingY;
                if ((i + 1) % ChildrenPerRow == 0)
                {
                    x -= SpacingX * (ChildrenPerRow - 1);
                    x += RowOffset;
                    y += ColumnOffset;
                }
                else
                {
                    x += SpacingX;
                }
            }

            return finalSize;
        }


        #endregion Methods
    }
}